package ai

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"

	"github.com/tidwall/gjson"
	"yx.io/qwq-ai/myComponent"
)

func Qwq(q string, ch chan string) string {

	return "qwq"
}

var (
	AppId  string
	ApiKey string
)

// 传入messages让模型进行回复，由于此方案会报错：{"code":"InternalError","message":"An internal error has occurred, please try again later or contact service support.","request_id":"adbb91f4-4124-9293-a646-6829446c8813"}
// 所以不使用此方案连续对话
func QwqStream(q string, ch chan string, messageList []myComponent.Message) {
	log.Printf("-------------------------------------messageList:%v", messageList)

	defer close(ch)

	appId := "6d9f58f611b148c48048f75fe4551761"
	// 若没有配置环境变量，可用百炼API Key将下行替换为：apiKey := "sk-xxx"。但不建议在生产环境中直接将API Key硬编码到代码中，以减少API Key泄露风险。
	apiKey := os.Getenv("DASHSCOPE_API_KEY")
	if apiKey == "" {
		apiKey = "sk-e028fa7e6f8843a2b47e08309751f243"
	}

	url := fmt.Sprintf("https://dashscope.aliyuncs.com/api/v1/apps/%s/completion", appId)

	// 创建请求体
	requestBody := map[string]any{
		"input": map[string]any{
			"prompt":   q,
			"messages": messageList,
			"stream":   true,
		},
		"parameters": map[string]any{
			"incremental_output": true, // 增量输出
			"has_thoughts":       true, // 输出思考过程

		},
		"debug": map[string]any{},
	}
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		fmt.Printf("无法序列化JSON: %v\n", err)
		return
	}

	// log.Printf("requestBody:%s", jsonData)

	// 创建 HTTP POST 请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Printf("创建请求失败: %v\n", err)
		return
	}

	// 设置请求头
	req.Header.Set("Authorization", "Bearer "+apiKey)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-DashScope-SSE", "enable") // 流式输出

	// 发送请求
	client := &http.Client{}

	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("发送请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		log.Printf("Request failed with status code: %d\n", resp.StatusCode)
		body, _ := io.ReadAll(resp.Body)
		log.Printf("body:%s", string(body))
		ch <- string(body)
		return
	}

	// 处理流式响应
	reader := io.Reader(resp.Body)
	buf := make([]byte, 1024)
	for {
		n, err := reader.Read(buf)
		if n > 0 {
			data := string(buf[:n])
			lines := strings.Split(data, "\n")
			for _, line := range lines {

				line = strings.TrimSpace(line)
				if len(line) >= 5 && line[:5] == "data:" {
					body := line[5:]
					log.Printf("line:%s", body)
					code := gjson.Get(body, "code").String()
					// 如果发生错误则直接返回
					if code == "InternalError" {
						value := gjson.Get(body, "message").String()
						ch <- value
						return
					}
					value := gjson.Get(body, "output.text").String()
					ch <- value
				}
			}
		}
		if err != nil {
			if err == io.EOF {
				break
			}
			fmt.Printf("读取响应失败: %v\n", err)
			break
		}
	}
}

// 直接传入session_id让模型根据session_id进行回复
func QwqStreamBySessionId(q string, ch chan string, sessionId string) {

	defer close(ch)

	url := fmt.Sprintf("https://dashscope.aliyuncs.com/api/v1/apps/%s/completion", AppId)

	// 创建请求体
	requestBody := map[string]any{
		"input": map[string]any{
			"prompt":     q,
			"session_id": sessionId,
			"stream":     true,
		},
		"parameters": map[string]any{
			"incremental_output": true, // 增量输出
			// "has_thoughts":       true, // 输出思考过程
		},
		"debug": map[string]any{},
	}
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		fmt.Printf("无法序列化JSON: %v\n", err)
		return
	}

	// 创建 HTTP POST 请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Printf("创建请求失败: %v\n", err)
		return
	}

	// 设置请求头
	req.Header.Set("Authorization", "Bearer "+ApiKey)
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-DashScope-SSE", "enable") // 流式输出

	// 发送请求
	client := &http.Client{}

	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("发送请求失败: %v\n", err)
		return
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		log.Printf("请求失败，状态码: %d\n", resp.StatusCode)
		body, _ := io.ReadAll(resp.Body)
		log.Printf("请求失败，body:%s", string(body))
		ch <- string(body)
		return
	}

	// 处理流式响应
	reader := io.Reader(resp.Body)
	buf := make([]byte, 1024)
	for {
		n, err := reader.Read(buf)
		if n > 0 {
			data := string(buf[:n])
			lines := strings.Split(data, "\n")
			for _, line := range lines {

				line = strings.TrimSpace(line)
				if len(line) >= 5 && line[:5] == "data:" {
					body := line[5:]
					// log.Printf("lineBody:%s", body)
					code := gjson.Get(body, "code").String()
					// 如果发生错误则直接返回
					if code == "InternalError" {
						value := gjson.Get(body, "message").String()
						ch <- value
						return
					}
					value := gjson.Get(body, "output.text").String()
					ch <- value
				}
			}
		}
		if err != nil {
			if err == io.EOF {
				break
			}
			fmt.Printf("读取响应失败: %v\n", err)
			break
		}
	}
}

func json2map(resp string) map[string]any {
	var result map[string]any
	err := json.Unmarshal([]byte(resp), &result)
	if err != nil {
		log.Printf("无法反序列化JSON: %v\n", err)
	}
	return result
}
